#pragma once

#include "../../Shared/GObjHelpers.hpp"
#include <set>

namespace BuildNG
{
  class VCPackage;

  struct VCPackagePtrComparer
  {
    bool operator () (const Glib::RefPtr<VCPackage> &a,const Glib::RefPtr<VCPackage> &b) const
    {
      return a.operator->() < b.operator->();
    }
  };

  typedef std::set<Glib::RefPtr<VCPackage>,VCPackagePtrComparer> VCPackageSet;

  class VCPackage : public Object
  {
  public:
    static Glib::RefPtr<VCPackage> get_package(const Glib::ustring &pkg_name,
      const Glib::ustring &configuration_name = "Debug");

    const Glib::ustring& get_cflags() const { return cflags; }
    const Glib::ustring& get_linker_flags() const { return linker_flags; }

    void get_dependencies_recursive(VCPackageSet &dest);

  private:
    VCPackage(const Glib::ustring &pkg_name,const Glib::ustring &configuration_name,
      std::vector<Glib::ustring> &dep_chain);

    static Glib::RefPtr<VCPackage> get_package(const Glib::ustring &pkg_name,
      const Glib::ustring &configuration_name,std::vector<Glib::ustring> &dep_chain);

    Glib::ustring     cflags;
    Glib::ustring     linker_flags;

    std::vector<Glib::RefPtr<VCPackage> > dependencies;

    struct PackageKey
    {
      Glib::ustring name;
      Glib::ustring configuration_name;

      bool operator < (const PackageKey &b) const
      {
        if(name != b.name)
          return name < b.name;
        else
          return configuration_name < b.configuration_name;
      }
    };
    typedef std::map<PackageKey,WeakPtr<VCPackage> >  PackageCache;
    typedef PackageCache::iterator                    PackageCacheIt;
    static PackageCache                               package_cache;
  };
}
